#新闻详情“收藏/评论/点赞
from . import news_blue
from flask import render_template,session,current_app,abort,g,jsonify,request
from info.models import User,News,Comment,CommentLike
from info import constants,db,response_code
from info.utils.comment import user_login_data


#关注
@news_blue.route('/followed_user', methods=['POST'])
@user_login_data
def followed_user():
    """关注和取消关注"""

    # 1.获取登录用户信息必须是登陆状态
    login_user = g.user
    if not login_user:
        return jsonify(errno=response_code.RET.SESSIONERR, errmsg='用户未登录')

    # 2.接受参数
    user_id = request.json.get('user_id')
    action = request.json.get('action')

    # 3.校验参数
    if not all([user_id,action]):
        return jsonify(errno=response_code.RET.PARAMERR, errmsg='缺少参数')
    if action not in ['follow','unfollow']:
        return jsonify(errno=response_code.RET.PARAMERR, errmsg='参数错误')

    # 4.查询要关注的人是否存在
    try:
        other = User.query.get(user_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmsg='查询用户失败')
    if not other:
        return jsonify(errno=response_code.RET.NODATA, errmsg='用户不存在')

    # 5.实现关注和取消关注
    if action == 'follow':
        # 关注
        if other not in login_user.followed:
            login_user.followed.append(other)
        else:
            return jsonify(errno=response_code.RET.DATAEXIST, errmsg='已关注')
    else:
        # 取消关注
        if other in login_user.followed:
            login_user.followed.remove(other)
        else:
            return jsonify(errno=response_code.RET.DATAEXIST, errmsg='未关注')

    # 6.同步到数据库
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmsg='保存到数据库失败')

    # 7.响应结果
    return jsonify(errno=response_code.RET.OK, errmsg='OK')
#点赞取消点赞
@news_blue.route('/comment_like',methods=['post'])
@user_login_data
def comment_like():
    """
    1获取登录信息
    2接收参数
    3校验参数
    4根据客户端传入的comment_id 查询除要点赞的评论
    5查询要点赞的评论的赞是否存在：查询当前登录用户是否给当前的评论点过赞
    6点赞取消点赞
    7同步数据库
    8响应结果
    :return:
    """

    # 1获取用户登录信息,并且要判断没有登录提示登录信息
    user = g.user
    if not user:
        return jsonify(errno=response_code.RET.SESSIONERR, errms='用户未登录')
    # 2接收参数
    comment_id = request.json.get('comment_id')
    action = request.json.get('action')
    #3校验参数
    if not all([comment_id,action]):
        return jsonify(errno=response_code.RET.PARAMERR, errmsg='缺少参数')
    if action not  in ['add','remove']:
        return jsonify(errno=response_code.RET.PARAMERR, errmsg='参数错误')
    #4根据客户段传入的comment_id 查询除要点赞的评论
    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmsg='查询评论失败')
    if not comment:
        return jsonify(errno=response_code.RET.NODATA, errmsg='评论不存在')

    #5查询要点赞的评论的赞是否被用户点过赞
    try:
        comment_like_model = CommentLike.query.filter(CommentLike.comment_id==comment_id,CommentLike.user_id==user.id).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmsg='查询点赞失败')
    #6点赞取消点赞
    if action =='add':
        #点赞
        if not comment_like_model:
            #创建模型类
            comment_like_model = CommentLike()
            comment_like_model.user_id = user.id
            comment_like_model.comment_id = comment_id
            # 将新的记录添加到数据库
            db.session.add(comment_like_model)
            #点赞数量的累计？
            comment.like_count += 1
    else:
        #取消点赞
        if comment_like_model:
            #将点赞删除
           db.session.delete(comment_like_model)
            # 点赞数量的累计？
           comment.like_count -= 1
    #7同步数据库
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmsg='操作失败')
    #8响应结果
    return jsonify(errno=response_code.RET.OK, errmsg='OK')
#评论
@news_blue.route('/news_comment',methods=['post'])
@user_login_data
def news_commment():
    """
    1登录信息
    2接收参数
    3校验参数
    4查询要评论的新闻是不是存在
    5实现新闻评论逻辑
    6响应评论结果
    :return:
    """
    # 1获取用户登录信息,并且要判断没有登录提示登录信息
    user = g.user
    if not user:
        return jsonify(errno=response_code.RET.SESSIONERR, errmsg='用户未登录')
    #2接收参数
    news_id = request.json.get('news_id')
    comment_content = request.json.get('comment')
    parent_id = request.json.get('parent_id')
    #3校验参数
    if not all([news_id,comment_content]):
        return jsonify(errno=response_code.RET.PARAMERR, errmsg='缺少参数')
    try: #传输是数字你能为其他
        news_id = int(news_id)
        if parent_id:
            parent_id = int(parent_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.PARAMERR, errmsg='参数错误')
    #4查询评论新闻是否存在
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmsg='查询新闻失败')
    if not news:
        return jsonify(errno=response_code.RET.NODATA, errmsg='新闻数据不存在')
    #5实现新闻评论逻辑
    comment = Comment()
    comment.user_id = user.id
    comment.news_id = news_id
    comment.content = comment_content
    #回复评论
    if parent_id:
        comment.parent_id = parent_id
    #同步到数据库
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmsg='评论失败')
    #响应评论结果
    return jsonify(errno=response_code.RET.OK, errmsg='OK',data=comment.to_dict())
#收藏 取消收藏
@news_blue.route('/news_collect',methods=['post'])
@user_login_data
def news_collect():
    """
    1获取用户登录信息
    2接收参数
    3校验参数
    4根据参数获取新闻信息
    5新闻收藏取消收藏
    6响应操作结果
    :return:
    """
    # 1获取用户登录信息,并且要判断没有登录提示登录信息
    user = g.user
    if not user:
        return jsonify(errno=response_code.RET.SESSIONERR, errmsg='用户未登录')
    #2接收参数 （1/新闻id 2/新闻收藏跟取消收藏）
    news_id = request.json.get('news_id')
    action = request.json.get('action')
    #3校验参数
    if not all([news_id,action]):
        return jsonify(errno=response_code.RET.PARAMERR, errmsg='缺少参数')
    if action not in ['collect','cancel_collect']:
        return jsonify(errno=response_code.RET.PARAMERR, errmsg='参数错误')
    # 4根据参数获取新闻信息
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmsg='查询新闻失败')
    if not news:
        return jsonify(errno=response_code.RET.NODATA, errmsg='新闻数据不存在')
    # 5新闻收藏取消收藏
    if action == 'collect':
        #当要收藏的新闻不再用户收藏列表中才需要收藏
       if news not in user.collection_news:
           user.collection_news.append(news)
    else:
       # 当要收藏的新闻在用户收藏列表中才需要取消收藏
       if news in user.collection_news:
           user.collection_news.remove(news)
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmsg='操作失败')
    #6响应操作结果
    return jsonify(errno=response_code.RET.OK, errmsg='操作成功')

#新闻详情页面
@news_blue.route('/detail/<int:news_id>')
@user_login_data
def news_detail(news_id):
    #新闻详情
    # 1获取用户信息
    #  2新闻点击排行
    # 3查询新闻查询
    # 4点击量的增加
    # 5收藏和取消收藏
    # 6展示用户的评论
    #7展示评论的赞
    #8展示作者关注
    user = g.user
    # 2.新闻点击排行展示
    # news_clicks = [News,News,News,News,News,News,News]
    news_clicks = []
    try:
       news_clicks = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
    # 3查询新闻详情
    news = None
    try:
       news = News.query.get(news_id)
    except Exception as e:
       current_app.logger.error(e)
       # 后续会给404的异常准备一个友好的提示页面
    if not news:
       abort(404)
    #4点击量的增加
    news.clicks += 1
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollabck()

    #5收藏和取消收藏
    is_collected = False
    if user:
        if news in user.collection_news:
            is_collected = True
    #6展示用户的评论
    comments = []
    try:
        comments = Comment.query.filter(Comment.news_id ==news_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)
    # 7展示评论的赞
    comment_like_ids = []
    if user:#登录状态
        try:
            #查询用户点赞的所有评论
            comment_likes = CommentLike.query.filter(CommentLike.user_id==user.id).all()
            #取出所有被用户点赞的评论的id
            comment_like_ids = [comment_like.comment_id for comment_like in comment_likes]
        except Exception as e:
            current_app.logger.error(e)
    # 因为我希望界面渲染的数据，是经过处理的，所以我不适用模型类原始的数据，而把每个模型类转成字典to_dict
    comment_dict_list = []
    for comment in comments:
        comment_dict = comment.to_dict()
        #给comment_dict追加一个is_like用以记录该评论是否被登录用户点赞了
        # 给comment_dict追加一个is_like用于记录该评论是否被登录用户点赞了
        # 14  ----  [21,22]   False
        # 15  ----  [21,22]   False ...
        # 21  ----  [21,22]   True
        # 22  ----  [21,22]   True
        comment_dict['is_list'] = False
        if comment.id in comment_like_ids:
            comment_dict['is_list'] = True
        comment_dict_list.append(comment_dict)
    #作者的关注
    is_followed = False

    # 当用户已登录且登录用户正在看的新闻有作者
    # user ； 176（登录用户）
    # news.user ： 佩奇（登录用户正在看的新闻的作者）
    if user and news.user:
        # news.user ： 佩奇
        # user.followed : 现在登陆a关注的人佩奇  followeds 佩奇下面的粉丝有没有a
        if news.user in user.followed:
            is_followed = True

    context = {
        'user': user.to_dict(),
        'news_clicks': news_clicks,
        'news': news.to_dict(),
        'is_collected':is_collected,
        'comments':comment_dict_list,
        'is_followed': is_followed

    }
    return render_template('news/detail.html',context =context)
